package com.cskaoyan.controller.wx_user;

import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.mall.order.Order;
import com.cskaoyan.bean.mall.order.OrderExample;
import com.cskaoyan.bean.temporary.TemporaryUser;
import com.cskaoyan.bean.user.Footprint;
import com.cskaoyan.bean.user.User;
import com.cskaoyan.bean.user.UserExample;
import com.cskaoyan.bean.wx_feedback.bo.WxFeedbackSubmitBo;
import com.cskaoyan.bean.wx_feedback.exception.AddFeedbackException;
import com.cskaoyan.bean.wx_feedback.exception.WxFeedbackParamException;
import com.cskaoyan.bean.wx_footprint.base.FootprintPageData;
import com.cskaoyan.bean.wx_footprint.base.FootprintParam;
import com.cskaoyan.bean.wx_footprint.bo.FootprintDeleteBo;
import com.cskaoyan.bean.wx_footprint.exception.DeleteFootprintException;
import com.cskaoyan.bean.wx_resp.WxRespVo;
import com.cskaoyan.bean.wx_user.bo.WxRegCaptchaBo;
import com.cskaoyan.bean.wx_user.bo.WxRegisteredBo;
import com.cskaoyan.bean.wx_user.bo.WxResetBo;
import com.cskaoyan.bean.wx_user.bo.WxUserLoginBo;
import com.cskaoyan.bean.wx_user.exception.AddUserException;
import com.cskaoyan.bean.wx_user.exception.WxUserParamException;
import com.cskaoyan.bean.wx_user.vo.IndexOrderVo;
import com.cskaoyan.bean.wx_user.vo.UserInfoVo;
import com.cskaoyan.bean.wx_user.vo.WxUserIndexOrderVo;
import com.cskaoyan.bean.wx_user.vo.WxUserLoginVo;
import com.cskaoyan.controller.wx_user.utils.WxFeedbackValidationUtil;
import com.cskaoyan.controller.wx_user.utils.WxUserValidationUtil;
import com.cskaoyan.mapper.mall.OrderMapper;
import com.cskaoyan.mapper.temporary.TemporaryUserMapper;
import com.cskaoyan.mapper.user.FootprintMapper;
import com.cskaoyan.mapper.user.UserMapper;
import com.cskaoyan.service.wx_feedback.WxFeedbackService;
import com.cskaoyan.service.wx_footprint.FootprintService;
import com.cskaoyan.service.wx_user.WxUserService;
import com.cskaoyan.shiro.MallToken;
import com.cskaoyan.utils.EncryptUtil;
import com.show.api.ShowApiRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;

/**
 * @author liXiaoFei
 * @date 2021/10/21 14:37
 */

@RestController
@RequestMapping("wx")
public class WxUserController {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    WxFeedbackService wxFeedbackService;

    @Autowired
    FootprintService footprintService;

    @Autowired
    UserMapper userMapper;

    @Autowired
    WxUserService wxUserService;

    @Autowired
    TemporaryUserMapper temporaryUserMapper;

    @Autowired
    FootprintMapper footprintMapper;

    private static final int UNRECV = 301;
    private static final int USER_UNCOMMENT = 401;
    private static final int SYSTEM_UNCOMMENT = 402;
    private static final int UNPAID = 101;
    private static final int UNSHIP = 201;


    @PostMapping("auth/login")
    public WxRespVo login(@RequestBody @Validated WxUserLoginBo wxUserLoginBo, BindingResult bindingResult,HttpServletRequest httpServletRequest) throws WxUserParamException {
        WxUserValidationUtil.valid(bindingResult);
        Subject subject = SecurityUtils.getSubject();
        MallToken mallToken = new MallToken(wxUserLoginBo.getUsername(), EncryptUtil.MD5(wxUserLoginBo.getPassword()) , "user");
        subject.login(mallToken);
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();

        addTemporaryFootPrint(user,httpServletRequest.getRemoteAddr());

        String token = subject.getSession().getId().toString();
        String addr = httpServletRequest.getRemoteAddr();
        wxUserService.updateUserInfoByLogin(user,addr);
        return WxRespVo.ok(new WxUserLoginVo(new UserInfoVo(user.getNickname(),user.getAvatar()),token));
    }

    private void addTemporaryFootPrint(User user,String ip) {
        List<TemporaryUser> temporaryUsers = temporaryUserMapper.selectTemporaryFootPrintByToday(ip);
        for (TemporaryUser temporaryUser : temporaryUsers) {
            Footprint footprint = new Footprint();
            footprint.setUserId(user.getId());
            footprint.setGoodsId(temporaryUser.getGoodsId());
            footprint.setAddTime(temporaryUser.getAddTime());
            footprint.setUpdateTime(temporaryUser.getAddTime());
            footprint.setDeleted(false);
            footprintMapper.insert(footprint);
        }

    }

    @GetMapping("user/index")
    public WxRespVo index(){
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        OrderExample example = new OrderExample();
        OrderExample.Criteria criteria = example.createCriteria();

        criteria.andUserIdEqualTo(user.getId());

        List<Order> orders = orderMapper.selectByExample(example);

        int unrecv = 0;
        int uncomment = 0;
        int unpaid = 0;
        int unship = 0;
        for (Order order : orders) {
            int orderStatus = order.getOrderStatus();
            switch (orderStatus){
                case UNPAID:
                    unpaid += 1;
                    break;
                case UNSHIP:
                    unship += 1;
                    break;
                case UNRECV:
                    unrecv += 1;
                    break;
                case USER_UNCOMMENT:
                    uncomment += 1;
                    break;
                case SYSTEM_UNCOMMENT:
                    uncomment += 1;
                    break;
            }
        }
        return WxRespVo.ok(new WxUserIndexOrderVo(new IndexOrderVo(unrecv,uncomment,unpaid,unship)));
    }

    @PostMapping("auth/logout")
    public WxRespVo logout(){
        SecurityUtils.getSubject().logout();
        return WxRespVo.ok();
    }


    @PostMapping("feedback/submit")
    public WxRespVo feedbackSubmit(@RequestBody WxFeedbackSubmitBo wxFeedbackSubmitBo,BindingResult bindingResult) throws WxFeedbackParamException, AddFeedbackException {
        WxFeedbackValidationUtil.valid(bindingResult);
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        wxFeedbackService.addFeedback(wxFeedbackSubmitBo,user);
        return WxRespVo.ok();
    }


    @GetMapping("footprint/list")
    public WxRespVo footprintList(FootprintParam footprintParam){
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        FootprintPageData data = footprintService.queryFootprintListByUser(footprintParam,user);
        return WxRespVo.ok(data);
    }

    @PostMapping("footprint/delete")
    public WxRespVo footprintDelete(@RequestBody FootprintDeleteBo footprintDeleteBo) throws DeleteFootprintException {
        footprintService.deleteFootprintById(footprintDeleteBo.getId());
        return WxRespVo.ok();
    }

    @PostMapping("auth/regCaptcha")
    public WxRespVo regCaptcha(HttpServletRequest httpServletRequest,@RequestBody WxRegCaptchaBo wxRegCaptchaBo ){
        String regCode = UUID.randomUUID().toString().substring(0,6);
        new ShowApiRequest("http://route.showapi.com/932-4","800424","b3472f35266a40daae5f168a9109bb0e")
                .addTextPara("toEmail",wxRegCaptchaBo.getMobile())
                .addTextPara("title","验证码")
                .addTextPara("checkcode",regCode)
                .addTextPara("length","6")
                .post();

        ServletContext context = httpServletRequest.getServletContext();
        context.setAttribute(httpServletRequest.getRemoteAddr(),regCode);

        return WxRespVo.ok();
    }

    @PostMapping("auth/register")
    public WxRespVo register(HttpServletRequest httpServletRequest,@RequestBody WxRegisteredBo wxRegisteredBo) throws AddUserException {
        List<User> users = getUsers(wxRegisteredBo.getMobile());
        if (users.size() != 0) return WxRespVo.error("该邮箱已被注册,请登录");

        String code = (String) httpServletRequest.getServletContext().getAttribute(httpServletRequest.getRemoteAddr());
        if (!wxRegisteredBo.getCode().equals(code)) return WxRespVo.errorRegister();

        User user = wxUserService.addUser(wxRegisteredBo);
        SecurityUtils.getSubject().login(new MallToken(user.getUsername(),user.getPassword(),"user"));
        String token = httpServletRequest.getSession().getId();
        return WxRespVo.ok(new WxUserLoginVo(new UserInfoVo(user.getUsername(),user.getAvatar()),token));
    }

    @PostMapping("auth/reset")
    public WxRespVo reset(HttpServletRequest httpServletRequest,@RequestBody WxResetBo wxResetBo){
        String mobile = wxResetBo.getMobile();
        List<User> users = getUsers(mobile);
        if (users.size() == 0) return WxRespVo.error("该邮箱没有注册，请注册");


        String code = (String) httpServletRequest.getServletContext().getAttribute(httpServletRequest.getRemoteAddr());
        if (!wxResetBo.getCode().equals(code)) return WxRespVo.errorRegister();

        User user = wxUserService.UpdateUserPassword(wxResetBo);
        SecurityUtils.getSubject().login(new MallToken(user.getUsername(),user.getPassword(),"user"));
        String token = httpServletRequest.getSession().getId();
        return WxRespVo.ok(new WxUserLoginVo(new UserInfoVo(user.getUsername(),user.getAvatar()),token));
    }

    @RequestMapping("auth/redirect")
    public WxRespVo redirect(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        return WxRespVo.errorWxLogin();
    }

    private List<User> getUsers(String mobile) {
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        criteria.andMobileEqualTo(mobile);

        return userMapper.selectByExample(example);
    }

}
